<template>
    <a-modal :keyboard="false" :maskClosable="false" title="权限编辑" :open="visible" :width="1100" :confirmLoading="loading" centered @ok="handleSubmit" @cancel="handleCancel">
        <a-form layout="vertical">
            <a-row :gutter="16">
                <a-col :span="8">
                    <a-row :gutter="16">
                        <a-col :span="12">
                            <a-form-item label="角色名称" v-bind="validateInfos.name">
                                <a-input v-model:value="modelRef.name" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="12">
                            <a-form-item label="角色编码" v-bind="validateInfos.code">
                                <a-input v-model:value="modelRef.code" :disabled="!isUndefined(modelRef.id)" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="12">
                            <a-form-item label="角色状态" v-bind="validateInfos.status">
                                <a-radio-group v-model:value="modelRef.status">
                                    <a-radio :value="1">正常</a-radio>
                                    <a-radio :value="0">冻结</a-radio>
                                </a-radio-group>
                            </a-form-item>
                        </a-col>
                        <a-col :span="12">
                            <a-form-item label="只看本人数据" v-bind="validateInfos.himself">
                                <a-radio-group v-model:value="modelRef.himself">
                                    <a-radio :value="1">是</a-radio>
                                    <a-radio :value="0">否</a-radio>
                                </a-radio-group>
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item label="评价不满意接单角色" v-bind="validateInfos.taskRoleId">
                                <a-select v-model:value="modelRef.taskRoleId" style="width: 100%">
                                    <a-select-option v-for="item in dictData.rolesList" :key="item.id">
                                        {{ item.name }}
                                    </a-select-option>
                                </a-select>
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item label="工单页面默认状态">
                                <a-radio-group v-model:value="modelRef.orderPage">
                                    <a-radio :value="0">全部</a-radio>
                                    <a-radio :value="1">待接单</a-radio>
                                    <a-radio :value="2">处理中</a-radio>
                                    <a-radio :value="3">待审核</a-radio>
                                    <a-radio :value="4">已审核</a-radio>
                                    <a-radio :value="5">待评价</a-radio>
                                    <a-radio :value="5">已完成</a-radio>
                                </a-radio-group>
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item label="权限分配" v-bind="validateInfos.pcMenuIds">
                                <a-tree-select
                                    v-model:value="modelRef.pcMenuIds"
                                    style="width: 100%"
                                    tree-checkable
                                    :height="233"
                                    :field-names="{
                                        children: 'children',
                                        label: 'name',
                                        value: 'id',
                                    }"
                                    :tree-data="dictData.menuData"
                                    :max-tag-count="3"
                                ></a-tree-select>
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item label="APP权限分配" v-bind="validateInfos.appMenuIds">
                                <a-tree-select
                                    v-model:value="modelRef.appMenuIds"
                                    style="width: 100%"
                                    tree-checkable
                                    tree-default-expand-all
                                    :height="233"
                                    :field-names="{
                                        children: 'children',
                                        label: 'name',
                                        value: 'id',
                                    }"
                                    :tree-data="dictData.appMenuData"
                                    :max-tag-count="3"
                                ></a-tree-select>
                            </a-form-item>
                        </a-col>
                    </a-row>
                </a-col>
                <a-col :span="16">
                    <a-form-item label="对应岗位" v-bind="validateInfos.postIds">
                        <a-transfer
                            style="width: 100%"
                            v-model:target-keys="modelRef.postIds"
                            :titles="['岗位', '已选择']"
                            :data-source="dictData.jobsData"
                            show-search
                            :filter-option="filterOption"
                            :render="item => item.title"
                            :listStyle="{ width: '300px' }"
                            pagination
                        />
                    </a-form-item>
                </a-col>
            </a-row>
        </a-form>
    </a-modal>
</template>

<script lang="ts">
    import type { PropType } from 'vue';
    import { defineComponent, reactive, ref, watchEffect, watch, nextTick } from 'vue';
    import { Form, message } from 'ant-design-vue';
    import { createRole, updateRole, getRole, getRoleAll } from '@/api/user/role';
    import { cloneDeep, isUndefined, isEmpty } from 'lodash-es';
    import type { Role, Permission } from '@/api/user/login';
    import { postList } from '@/api/common/mdm';
    import { getMenuListTree } from '@/api/user/menu';

    export default defineComponent({
        props: {
            visible: {
                type: Boolean,
                required: true,
            },
            model: {
                type: Object as PropType<Role | null>,
                default: () => null,
            },
        },
        emits: ['cancel', 'success'],
        setup(props, { emit }) {
            const loading = ref(false);
            const dictData = reactive<any>({
                jobsData: [],
                menuData: [],
                rolesList: [],
            });
            const defaultForm = {
                name: '',
                code: '',
                status: 1,
                himself: 1,
                orderPage: 1,
                appMenuIds: [],
                pcMenuIds: [],
            };
            const modelRef = reactive<any>(cloneDeep(defaultForm));
            const rulesRef = reactive({
                name: [{ required: true, message: '请输入角色名称' }],
                code: [{ required: true, message: '请输入角色编码' }],
                himself: [{ required: true, message: '请选择' }],
                taskRoleId: [{ required: true, message: '请选择' }],
            });
            const rolePermissions = ref<Permission[]>([]);

            const { validateInfos, resetFields, validate } = Form.useForm(modelRef, rulesRef);

            // 记录初始值
            const initValues = reactive({});
            watch(
                () => props.visible,
                () => {
                    Object.assign(initValues, cloneDeep(props.model));
                },
            );
            watchEffect(() => {
                if (props.visible) {
                    postList().then(res => {
                        if (res.data.length > 0) {
                            dictData.jobsData = res.data.map(item => {
                                return {
                                    key: item.id,
                                    title: item.name,
                                    description: item.name,
                                };
                            });
                        }
                    });
                    getMenuListTree({
                        menuType: '0',
                    }).then(res => {
                        if (!isEmpty(res.data)) {
                            dictData.menuData = res.data;
                        }
                    });
                    getRoleAll().then(res => {
                        if (!isEmpty(res.data)) {
                            dictData.rolesList = res.data;
                        }
                    });
                    getMenuListTree({
                        menuType: '1',
                    }).then(res => {
                        if (!isEmpty(res.data)) {
                            dictData.appMenuData = res.data;
                        }
                    });
                    if (props.model) {
                        Object.assign(modelRef, props.model);
                        // 这一步可以不用，直接传递 model.permissions 到页面进行渲染
                        // 这里重新组装是为了演示结构不相同情况下可以按照下列方案组装结构
                        getRole(props.model.id).then(res => {
                            nextTick(() => {
                                const { pcMenuIds, appMenuIds, postIds } = res.data;
                                Object.assign(modelRef, res.data, {
                                    postIds: isEmpty(postIds) ? [] : postIds,
                                    appMenuIds: isEmpty(appMenuIds) ? [] : appMenuIds,
                                    pcMenuIds: isEmpty(pcMenuIds) ? [] : pcMenuIds,
                                });
                            });
                        });
                    }
                }
            });

            const filterOption = (inputValue: string, option: any) => {
                return option.title.includes(inputValue);
            };

            const handleCancel = () => {
                resetFields();
                emit('cancel');
                Object.keys(modelRef).forEach(key => {
                    delete modelRef[key];
                });
                Object.assign(modelRef, cloneDeep(defaultForm));
            };

            const handleSubmit = async () => {
                validate().then(() => {
                    loading.value = true;
                    const { appMenuIds, pcMenuIds, ...lastData } = modelRef;
                    (isUndefined(modelRef.id) ? createRole : updateRole)({
                        ...lastData,
                        menuIds: [...pcMenuIds, ...appMenuIds],
                    })
                        .then(res => {
                            if (res.data) {
                                message.success('操作成功');
                                emit('success');
                                handleCancel();
                            }
                        })
                        .finally(() => {
                            loading.value = false;
                        });
                });
            };

            return {
                loading,

                modelRef,
                validateInfos,
                resetFields,

                handleSubmit,
                handleCancel,

                rolePermissions,

                initValues,

                dictData,
                filterOption,

                isUndefined,
            };
        },
    });
</script>
